fix(ce-compound): quote YAML array items starting with reserved indicators#607
fix(ce-compound): quote YAML array items starting with reserved indicators#607nathanvale wants to merge 1 commit intoEveryInc:mainfrom
Conversation
…ators Array items in frontmatter fields like `symptoms:` that start with a backtick or other YAML 1.2 reserved indicator (`, [, *, &, !, |, >, %, @, ?) or contain `: ` must be wrapped in double quotes — otherwise strict parsers (`yq`, `js-yaml` strict, PyYAML) reject the file. `ce-learnings-researcher`'s grep-first retrieval still matches, masking the problem until a structural consumer fails. Encode the rule in the support-file contract that every ce-compound and ce-compound-refresh subagent reads at write time: - Add a validation rule to `references/schema.yaml` - Add a "YAML Safety Rules" section to `references/yaml-schema.md` with indicator list, `: ` trap, and before/after example - Add preamble comments above each frontmatter block in `assets/resolution-template.md` - Add one-line pointers at the three SKILL.md spots that write or dispatch writes of frontmatter - Add 8 regression tests asserting the rule is present in every surface; mutation-tested by removing the rule and confirming failure Support-file edits are applied to both skill copies in the same commit to keep `tests/compound-support-files.test.ts` drift assertions green. Fixes EveryInc#606. Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3895b1acf7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const mentions = raw.match(/yaml-schema\.md/g) ?? [] | ||
| // Both Full-mode Phase 2 step 5 and Lightweight mode step 3 should mention the rule. | ||
| expect(mentions.length).toBeGreaterThanOrEqual(2) |
There was a problem hiding this comment.
Require YAML-safety pointers in each ce-compound write path
This test claims to protect both frontmatter-writing locations, but mentions.length >= 2 counts all yaml-schema.md occurrences in the file, including unrelated references. Because ce-compound/SKILL.md already contains a non-write-path mention, one of the two targeted write-path pointers can be removed and the test will still pass. That leaves either Full mode or Lightweight mode unprotected against regressing the YAML-quoting guidance.
Useful? React with 👍 / 👎.
|
@nathanvale Thanks for the contribution!
|
|
Closing in favor of #613 |
Summary
Fixes #606 —
/ce-compoundemits invalid YAML frontmatter when an array item insymptoms:,applies_when:,tags:,related_components:(or any future array-of-strings field) starts with a backtick or other YAML 1.2 reserved indicator. Strict parsers (yq,js-yamlstrict, PyYAML) reject the file;ce-learnings-researcher's grep-first retrieval still matches on substrings, so users silently accumulate unparseable files until a structural consumer fails.This PR encodes the quoting rule in the support-file contract that every
ce-compoundandce-compound-refreshsubagent reads at write time, then reinforces it with one-line pointers at the threeSKILL.mdspots that write or dispatch writes of frontmatter, and a preamble comment on the frontmatter template. A regression test asserts the rule is present in every surface.Same shape of fix as #603 (which handled the
description:angle-bracket-token case): codify the rule + add a test.Changes
references/schema.yamlvalidation_rulesentry for array-item quotingreferences/yaml-schema.md": "trap, and before/after exampleassets/resolution-template.mdce-compound/SKILL.mdce-compound-refresh/SKILL.mdtests/compound-support-files.test.tsSKILL.mdfilesSupport-file edits are applied to both skill copies in the same commit to keep
tests/compound-support-files.test.ts's existing drift assertions green.Rule body lives in the on-demand-loaded reference file, not in
SKILL.md— keeps the load-time token footprint flat per pluginAGENTS.mdRationale Discipline.Scope Boundaries
description:or other scalar string fields — fix(ce-release-notes): backtick-wrap<skill-name>token in description #603 already covered that.ce-brainstorm,ce-plan,ce-release-notes). Each has its own prompt surface; this PR addressesce-compoundandce-compound-refreshonly.Test plan
bun test tests/compound-support-files.test.ts— 11/11 pass (3 drift + 8 new regression)bun test tests/frontmatter.test.ts— 192/192 pass (SKILL.md frontmatter validity preserved)validation_rulesentry → 2 expected failures fire (the YAML-safety assertion + the drift test). Rule presence is enforced.tests/resolve-base.sh > resolves against origin/HEAD in a detached shallow checkout) reproduces on cleanmainin this shallow-clone checkout and is unrelated to these changes.Plan document:
docs/plans/2026-04-20-001-fix-ce-compound-yaml-safety-plan.md(included in the commit for traceability).